package com.dreamana.ui
{
	import com.dreamana.command.BaseCommand;
	
	import flash.display.Bitmap;
	import flash.display.Loader;
	import flash.events.Event;
	import flash.events.IEventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.net.URLRequest;
	import flash.net.URLStream;
	import flash.utils.ByteArray;
	import flash.utils.setTimeout;
	
	public class SkinStreamCommand extends BaseCommand
	{
		private var _url:String;
		private var _decoder:Loader;
		private var _stream:URLStream;
		private var _buffer:ByteArray;
		
		public function SkinStreamCommand(url:String)
		{
			_url = url;
			_decoder = new Loader();
			_stream = new URLStream();
			_buffer = new ByteArray();
		}
		
		override public function execute():void
		{
			this.registerListeners(_stream);
			_stream.load(new URLRequest(_url)); 
		}
				
		private function updateBytes():void
		{
			if(_stream.connected) _stream.readBytes(_buffer, _buffer.length);
			
			if(_buffer.length > 0)
			{
				//Note: loadBytes() is async method
				_decoder.loadBytes(_buffer);
			}			
		}
		
		private function registerListeners(dispatcher:IEventDispatcher):void
		{
			dispatcher.addEventListener(Event.COMPLETE, onStreamComplete);
			dispatcher.addEventListener(IOErrorEvent.IO_ERROR, onStreamIOError);
			dispatcher.addEventListener(ProgressEvent.PROGRESS, onStreamProgress);
		}
		
		private function unregisterListeners(dispatcher:IEventDispatcher):void
		{
			dispatcher.removeEventListener(Event.COMPLETE, onStreamComplete);
			dispatcher.removeEventListener(IOErrorEvent.IO_ERROR, onStreamIOError);
			dispatcher.removeEventListener(ProgressEvent.PROGRESS, onStreamProgress);
		}
		
		//--- EVENT HANDLERS ---
		
		private function onStreamComplete(e:Event):void
		{
			//hack
			setTimeout(confirmBytesLoaded, 500);
		}
		private function confirmBytesLoaded():void
		{
			updateBytes();
			if(_stream.connected) _stream.close();
			
			this.unregisterListeners(_stream);
			
			//complete
			this.complete();
		}
		
		private function onStreamProgress(e:ProgressEvent):void
		{
			updateBytes();
		}
		
		private function onStreamIOError(e:IOErrorEvent):void
		{
			this.unregisterListeners(_stream);
			
			trace(e.text);
			
			//complete
			this.complete();
		}
		
		//--- GETTER/SETTERS ---
		public function set url(value:String):void { _url = value; }
		public function get url():String { return _url; }
		
		public function get stream():URLStream { return _stream; }
		public function get loader():Loader { return _decoder; }
	}
}